package com.zgjkhis.modules.system.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zgjkhis.common.service.impl.BaseServiceImpl;
import com.zgjkhis.exception.ServiceException;
import com.zgjkhis.modules.charges.domain.PrescriptionOrder;
import com.zgjkhis.modules.charges.domain.PrescriptionRefund;
import com.zgjkhis.modules.charges.domain.PrescriptionRefundDetail;
import com.zgjkhis.modules.charges.service.PrescriptionRefundDetailService;
import com.zgjkhis.modules.charges.service.PrescriptionRefundService;
import com.zgjkhis.modules.charges.service.PrescriptionService;
import com.zgjkhis.modules.outpatient.dto.ChargeOrderCriteria;
import com.zgjkhis.modules.outpatient.dto.RefundOrderDto;
import com.zgjkhis.modules.security.security.LoginUserUtil;
import com.zgjkhis.modules.system.domain.*;
import com.zgjkhis.modules.system.domain.vo.RefundInfoDetailVO;
import com.zgjkhis.modules.system.domain.vo.RefundInfoVO;
import com.zgjkhis.modules.system.domain.vo.RefundOrderVO;
import com.zgjkhis.modules.system.service.*;
import com.zgjkhis.modules.system.service.mapper.OrderMapper;
import com.zgjkhis.modules.util.CharUtil;
import com.zgjkhis.modules.util.ConnectionUrlUtil;
import com.zgjkhis.utils.DateUtils;
import com.zgjkhis.utils.RandomUtils;
import com.zgjkhis.utils.SecurityUtils;
import com.zgjkhis.utils.SpringContextHolder;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;

/**
 * @Author yzq
 * @Description 订单
 * @Date 2021/6/23 9:47
 * @Param
 * @return
 **/
@Service
@AllArgsConstructor
//@CacheConfig(cacheNames = "user")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
@Slf4j
public class OrderServiceImpl extends BaseServiceImpl<OrderMapper, Order> implements OrderService {

    private final DrugService drugService;

    private final InfoDrugService infoDrugService;

    private final InfoService infoService;

    private final ConsultService consultService;

    private final ApiChannelStoreService apiChannelStoreService;

    private final OrderAddressService orderAddressService;

    private final PrescriptionService prescriptionService;

    private final OrderComfireService orderComfireService;

    private final DrugWareHousingDetailService drugWareHousingDetailService;

    private final PrescriptionRefundService prescriptionRefundService;

    private final PrescriptionRefundDetailService prescriptionRefundDetailService;

    private final DoctorService doctorService;

    private final DrugCirculationService drugCirculationService;

    private final MessageService messageService;

    private final StoreService storeService;

    @Transactional
    @Override
    public JSONObject createOrder(String data, ApiChannel apiChannel) {
        JSONObject response = new JSONObject();
        JSONObject json = JSONObject.parseObject(data);
        String orderNo = json.getString("order_no");
        try {

            //解析处理订单
            Order order = new Order();
            Order ord = this.getOne(Wrappers.<Order>query().lambda().eq(Order::getApiOrderNo, orderNo));
            if (!CharUtil.isEmpty(ord)) {
                response.put("status", "0");
                response.put("message", "请勿重复提交订单");
                response.put("order_no", orderNo);
                return response;
            }
            String orderNoa = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
            String orderTime = json.getString("order_time");
            String doctorName = json.getString("doctor_name");
            String doctorId = json.getString("doctor_id");
            String patientName = json.getString("patient_name");
            Integer patientSex = json.getInteger("patient_sex");
            String patientAge = json.getString("patient_age");
            String expressCode = json.getString("express_code");
            String machinFee = json.getString("machin_fee");
            String expressFee = json.getString("express_fee");
            String pharmacyId = json.getString("pharmacy_id");
            String remark = json.getString("remark");
            String payTime = json.getString("pay_time");
            String drugCost = json.getString("drugCost");
            String baseDrugCost = json.getString("baseDrugCost");

            if (CharUtil.isEmpty(orderNo) || CharUtil.isEmpty(orderTime) || CharUtil.isEmpty(doctorName) || CharUtil.isEmpty(doctorId) ||
                    CharUtil.isEmpty(patientName) || CharUtil.isEmpty(patientSex) || CharUtil.isEmpty(patientAge) ||
                    CharUtil.isEmpty(pharmacyId)) {
                throw new ServiceException("订单必填项不可为空");
            }

            if (CharUtil.isEmpty(machinFee)) {
                throw new ServiceException("咨询费不能为空");
            }

            if (CharUtil.isEmpty(drugCost)) {
                drugCost = "0";
            }
            if (CharUtil.isEmpty(baseDrugCost)) {
                baseDrugCost = "0";
            }

            //根据渠道id，和药房id，匹配出his系统的门店id
            ApiChannelStore apiChannelStore = apiChannelStoreService.getOne(Wrappers.<ApiChannelStore>query().lambda().eq(ApiChannelStore::getStatus, 0)
                    .eq(ApiChannelStore::getChannelId, apiChannel.getId()).eq(ApiChannelStore::getPharmacyId, pharmacyId));
            if (CharUtil.isEmpty(apiChannelStore)) {
                throw new ServiceException("药房id【" + pharmacyId + "】不存在核销门店，请联系管理员配置");
            }
            pharmacyId = apiChannelStore.getHisStoreId();

            String diagnosis = json.getString("diagnosis");
            String complaint = json.getString("complaint");
            String hpi = json.getString("hpi");

            String consultNo = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
            Consult consult = new Consult();
            consult.setConsultNo(consultNo);
            consult.setConsultDocName(doctorName);
            consult.setPatientName(patientName);
            consult.setConsultComplaint(complaint);//主诉

            consult.setConsultHpi(hpi);
            consult.setDiagnosis(diagnosis);
            consult.setConsultType(1);
            consult.setConsultFlag(3);
            consult.setPharmacyId(pharmacyId);

            //查找医生
            Doctor doctor = doctorService.getOne(Wrappers.<Doctor>query().lambda().eq(Doctor::getSourceId, doctorId).eq(Doctor::getStatus, 0));
            if (CharUtil.isEmpty(doctor)) {
                Doctor doc = new Doctor();
                doc.setDoctorName(doctorName);
                doc.setSourceId(doctorId);
                doc.setPharmacyId(pharmacyId);
                doc.setType(2);
                doctorService.save(doc);
                order.setDocId(doc.getId().toString());
                consult.setConsultDocId(doc.getId().toString());
            } else {
                order.setDocId(doctor.getId().toString());
                consult.setConsultDocId(doctor.getId().toString());
                if (!doctor.getPharmacyId().contains(pharmacyId)) {
                    Doctor doc = new Doctor();
                    doc.setId(doctor.getId());
                    doc.setPharmacyId(doctor.getPharmacyId() + "," + pharmacyId);
                    doctorService.updateById(doc);
                }
            }
            order.setOrderNo(orderNoa);
            order.setApiOrderNo(orderNo);
            order.setOrderTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", orderTime));
            order.setDocName(doctorName);
            order.setPatientName(patientName);
            order.setPatientSex(patientSex);
            order.setPatientAge(patientAge);
            order.setExpressCode(expressCode);
            order.setRemark(remark);
            order.setSourceStoreId(apiChannelStore.getPharmacyId());
            order.setSourceStoreName(apiChannelStore.getPharmacyName());
            if (!CharUtil.isEmpty(payTime)) {
                order.setPayTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", payTime));
            }
            if ("-1".equals(expressCode)) {
                order.setDeliveryType(2);//方式，邮寄，自取 //计算补充
                order.setExpressFee(BigDecimal.ZERO);
            } else {
                if (CharUtil.isEmpty(expressFee)) {
                    throw new ServiceException("请输入邮寄费");
                }
                order.setDeliveryType(1);//邮寄
                order.setExpressFee(BigDecimal.valueOf(Double.valueOf(expressFee)));
            }
            order.setMachinFee(BigDecimal.valueOf(Double.valueOf(machinFee)));
            order.setTotalFee(BigDecimal.ZERO); //计算补充
            order.setOrderStatus(0);
            order.setOrderType(2);
            order.setPayStatus(1);
            order.setPharmacyId(pharmacyId);
            order.setConsultNo(consultNo);
            order.setSource(apiChannel.getAppName());
            order.setSourceId(apiChannel.getAppId());
            //解析处理 订单地址
            OrderAddress orderAddress = new OrderAddress();
            if (!"-1".equals(expressCode)) {
                //邮寄地址
                String consignee = json.getString("consignee");
                String mobile = json.getString("mobile");
                String province = json.getString("province");
                String provinceCode = json.getString("provinceCode");
                String city = json.getString("city");
                String cityCode = json.getString("cityCode");
                String district = json.getString("district");
                String districtCode = json.getString("districtCode");
                String address = json.getString("address");
                if (CharUtil.isEmpty(consignee) || CharUtil.isEmpty(mobile) || CharUtil.isEmpty(province) ||
                        CharUtil.isEmpty(city) || CharUtil.isEmpty(district) || CharUtil.isEmpty(address)) {
                    throw new ServiceException("邮寄订单,邮寄地址不能为空");
                }
                orderAddress.setUsername(consignee);
                orderAddress.setPhone(mobile);
                orderAddress.setProvince(province);
                orderAddress.setProvinceCode(provinceCode);
                orderAddress.setCity(city);
                orderAddress.setCityCode(cityCode);
                orderAddress.setArea(district);
                orderAddress.setAreaCode(districtCode);
                orderAddress.setAddress(address);
                orderAddress.setOrderNo(orderNoa);
                orderAddressService.save(orderAddress);
            }
            //解析处理订单处方
            JSONArray pstarray = json.getJSONArray("pst_items");
            List<Info> infos = new ArrayList<>();
            response.put("his_order_no", orderNoa);
            response.put("order_no", orderNo);
            List<JSONObject> list = new ArrayList<>();
            Map<String, List<InfoDrug>> maps = new HashMap<>();
            for (int i = 0; i < pstarray.size(); i++) {
                JSONObject obj = new JSONObject();
                BigDecimal pstFee = BigDecimal.ZERO;

                JSONObject pstJson = pstarray.getJSONObject(i);
                String pstNo = pstJson.getString("pst_no");
                String source = pstJson.getString("source");
                String pstNoa = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
                String isPosted = pstJson.getString("is_posted");
                if (CharUtil.isEmpty(isPosted)) {
                    isPosted = "1";
                }
                String prescriptionType = pstJson.getString("prescription_type");
                Integer pstType = pstJson.getInteger("pst_type");
                Integer dosageForm = pstJson.getInteger("dosage_form");
                Integer num = pstJson.getInteger("num");
                String takeMethod = pstJson.getString("take_method");
                String frequency = pstJson.getString("frequency");
                String useFlag = pstJson.getString("useFlag");
                String phRemark = pstJson.getString("phRemark");
                String useRequire = pstJson.getString("use_require");
                obj.put("pst_no", pstNo);

                if ("1".equals(prescriptionType)) {
                    //中药处方
                    if (CharUtil.isEmpty(pstType) || CharUtil.isEmpty(dosageForm) || CharUtil.isEmpty(num)) {
                        throw new ServiceException(pstNo + "处方必填项不能为空");
                        //                    obj.put("message","处方必填项不能为空");
                        //                    continue;
                    }
                }
                Info info = new Info();
                info.setInfoNo(pstNoa);
                info.setSource(CharUtil.isEmpty(source) ? 1 : Integer.valueOf(source));
                info.setApiInfoNo(pstNo);
                info.setIsPosted(Integer.valueOf(isPosted));
                info.setPharmacyId(pharmacyId);
                info.setPstType(pstType);
                info.setDosageForm(dosageForm);
                info.setOrderNo(orderNoa);
                info.setPatientName(patientName);
                info.setDocId(order.getDocId());
                info.setDocName(doctorName);
                info.setPharmacyId(pharmacyId);
                info.setUseFlag(useFlag);
                info.setPhRemark(phRemark);
                info.setPrescriptionType(Integer.valueOf(prescriptionType));
                info.setPayStatus(1);//已支付
                info.setOrderCondition(1);//待审方
                if ("1".equals(prescriptionType) || "3".equals(prescriptionType)) { //中药处方（颗粒剂，饮片）
                    info.setFrequency(frequency);
                    info.setUseRequire(useRequire);
                    info.setTakeMethod(takeMethod);
                    info.setNum(num);
                } else {
                    info.setNum(1);
                }
                info.setConsultNo(consultNo);
                //解析处理订单处方详情
                JSONArray drugarray = pstJson.getJSONArray("medicines");
                if (CharUtil.isEmpty(drugarray) || drugarray.size() <= 0) {
                    throw new ServiceException("处方：" + pstNo + "处方列表不能为空");
                }
                List<InfoDrug> infoDrugs = new ArrayList<>();
                String errormsg = "";
                BigDecimal curPstFee = BigDecimal.ZERO;
                List<String> cirOderNos = new ArrayList<>();
                List<String> cirInfoNos = new ArrayList();
                for (int j = 0; j < drugarray.size(); j++) {
                    JSONObject drug = drugarray.getJSONObject(j);
                    String code = drug.getString("code");
                    String name = drug.getString("name");
                    String dose = drug.getString("dose");
                    String doseUnit = drug.getString("dose_unit");
                    String frequencyDrug = drug.getString("frequency_drug");
                    String quantity = drug.getString("quantity");
                    String usageName = drug.getString("usage_name");
                    String decoctionName = drug.getString("decoction_name");
                    String discount = drug.getString("discount");
                    String saleprice = drug.getString("sale_price");
                    String oldprice = drug.getString("old_price");
                    String drugUseFlag = drug.getString("useFlag");
                    if (CharUtil.isEmpty(code) || CharUtil.isEmpty(name) || CharUtil.isEmpty(dose)
                            || CharUtil.isEmpty(doseUnit)) {
                        //                    errormsg="药材数组必填项不能为空";
                        //                    break;
                        throw new ServiceException(pstNo + "药材数组必填项不能为空");
                    }
                    if (CharUtil.isEmpty(discount)) {
                        discount = "1";
                    }
                    InfoDrug infoDrug = new InfoDrug();
                    infoDrug.setInfoNo(pstNoa);
                    infoDrug.setOrderNo(orderNoa);
                    infoDrug.setDrugId(Long.valueOf(code));
                    infoDrug.setDrugName(name);
                    Drug temp = drugService.getOne(Wrappers.<Drug>query().lambda().eq(Drug::getId, code).eq(Drug::getStatus, 0).eq(Drug::getPharmacyId, pharmacyId));
                    if (CharUtil.isEmpty(temp)) {
                        throw new ServiceException("处方：" + pstNo + "药品编码【" + code + "】不存在");
                        //                    errormsg="药品编码【"+code+"】不存在";
                        //                    break;
                    }
                    infoDrug.setSpecification(temp.getDrugSpec());
                    infoDrug.setStatus(1);
                    infoDrug.setDoseUnit(doseUnit);
                    infoDrug.setTotalDoseUnit(temp.getTotalDoseUnit());
                    infoDrug.setDose(BigDecimal.valueOf(Double.valueOf(dose)));
                    infoDrug.setQuantity((int) Double.parseDouble(quantity));
                    infoDrug.setPackUnit(temp.getPackageUnit());
                    infoDrug.setUseUnit(temp.getPackageUnit());//api接口使用包装单位
                    infoDrug.setDiscount(discount);
                    infoDrug.setPrice(BigDecimal.valueOf(Double.valueOf(oldprice)));//原价
                    infoDrug.setDiscountPrice(BigDecimal.valueOf(Double.valueOf(saleprice)));//折扣价格
                    infoDrug.setPharmacyId(pharmacyId);
                    infoDrug.setUseFlag(drugUseFlag);
                    if ("2".equals(prescriptionType)) {
                        //成药处方
                        infoDrug.setFrequency(frequencyDrug);
                        infoDrug.setPharmacyId(pharmacyId);
                        infoDrug.setUsageName(usageName);
                    } else if ("1".equals(prescriptionType)) {
                        //中药处方
                        infoDrug.setDecoctionName(decoctionName);
                    }
                    pstFee = pstFee.add(infoDrug.getDiscountPrice().multiply(BigDecimal.valueOf(infoDrug.getQuantity())));
                    //判断该药品是否需要流转

                    DrugCirculation drugCirculation = drugCirculationService.getOne(Wrappers.<DrugCirculation>query().lambda().eq(DrugCirculation::getStatus, 0).eq(DrugCirculation::getFromDrugId, code).eq(DrugCirculation::getFromStoreId, pharmacyId));
                    if (!CharUtil.isEmpty(drugCirculation)) {
                        //需要流转
                        InfoDrug cirTemp = new InfoDrug();
                        BeanUtils.copyProperties(infoDrug, cirTemp);

                        //从map种获取相同门店的药品
                        List<InfoDrug> tempList = maps.get(info.getInfoNo() + drugCirculation.getToStoreId());
                        String cirOrderNo = "";
                        String cirInfoNo = "";
                        if (CharUtil.isEmpty(tempList)) {
                            tempList = new ArrayList<>();
                            cirOrderNo = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
                            cirInfoNo = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
                            cirOderNos.add(cirOrderNo);
                            cirInfoNos.add(cirInfoNo);
                        } else {
                            cirOrderNo = tempList.get(0).getOrderNo();
                            cirInfoNo = tempList.get(0).getInfoNo();
                        }
                        infoDrug.setIsCirulation(1);
                        infoDrug.setCirOrderNo(cirOrderNo);
                        infoDrug.setCirInfoNo(cirInfoNo);
                        infoDrug.setCirDrugId(drugCirculation.getToDrugId());
                        cirTemp.setOrderNo(cirOrderNo);
                        cirTemp.setInfoNo(cirInfoNo);
                        cirTemp.setPharmacyId(drugCirculation.getToStoreId().toString());
                        cirTemp.setDrugId(drugCirculation.getToDrugId());
                        curPstFee = curPstFee.add(cirTemp.getDiscountPrice().multiply(BigDecimal.valueOf(cirTemp.getQuantity())));
                        tempList.add(cirTemp);
                        maps.put(info.getInfoNo() + drugCirculation.getToStoreId().toString(), tempList);
                    }
                    infoDrugs.add(infoDrug);
                }
                //            totalFee=totalFee.multiply(BigDecimal.valueOf(info.getNum()));

                if (CharUtil.isEmpty(errormsg)) {
                    obj.put("his_pst_no", pstNoa);
                    obj.put("message", "ok");
                    obj.put("status", "1");
                } else {
                    obj.put("message", errormsg);
                    obj.put("his_pst_no", "");
                    obj.put("status", "0");
                }
                infoDrugService.saveBatch(infoDrugs);
                info.setTotalPay(pstFee);
                info.setDrugCost(BigDecimal.valueOf(Double.valueOf(drugCost)));
                info.setCourseCost(BigDecimal.valueOf(Double.valueOf(baseDrugCost)));
                info.setProcessCost(order.getMachinFee());
                info.setCirulationCost(curPstFee);
                info.setCirOrderNo(StringUtils.join(cirOderNos, ","));
                info.setCirInfoNo(StringUtils.join(cirInfoNos, ","));
                infos.add(info);
                list.add(obj);
            }
            order.setDrugCost(BigDecimal.valueOf(Double.valueOf(drugCost)));
            order.setTotalFee(order.getDrugCost().add(order.getMachinFee()));
            order.setActualCharge(order.getTotalFee().add(order.getExpressFee()));
            order.setPayWay(6);
            order.setCirulationCost(infos.stream().map(Info::getCirulationCost).reduce(BigDecimal.ZERO, BigDecimal::add));
            order.setCirOrderNo(infos.stream().map(Info::getCirOrderNo).collect(Collectors.joining(",")));
            order.setCirInfoNo(infos.stream().map(Info::getCirInfoNo).collect(Collectors.joining(",")));

            //保存流转订单
            if (!CharUtil.isEmpty(maps)) {
                List<Info> cirInfos = new ArrayList<>();
                List<Order> cirOrders = new ArrayList<>();
                List<Message> messages = new ArrayList<>();
                Iterator<Map.Entry<String, List<InfoDrug>>> iterator = maps.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, List<InfoDrug>> entry = iterator.next();
                    List<InfoDrug> value = entry.getValue();

                    //组装处方
                    Info cirInfo = new Info();
                    BeanUtils.copyProperties(infos.get(0), cirInfo);
                    BigDecimal payFee = BigDecimal.ZERO;
                    for (InfoDrug tempInfoDrug : value) {
                        payFee = payFee.add(tempInfoDrug.getDiscountPrice().multiply(BigDecimal.valueOf(tempInfoDrug.getQuantity())));
                    }
                    cirInfo.setTotalPay(payFee);
                    cirInfo.setDrugCost(payFee);
                    cirInfo.setCourseCost(BigDecimal.ZERO);
                    cirInfo.setProcessCost(BigDecimal.ZERO);
                    cirInfo.setCirulationCost(BigDecimal.ZERO);
                    cirInfo.setInfoNo(value.get(0).getInfoNo());
                    cirInfo.setOrderNo(value.get(0).getOrderNo());
                    cirInfo.setCirOrderNo(null);
                    cirInfo.setCirInfoNo(null);
                    cirInfo.setPharmacyId(value.get(0).getPharmacyId());
                    cirInfos.add(cirInfo);
                    //组装订单
                    Order cirOrder = new Order();
                    BeanUtils.copyProperties(order, cirOrder);
                    cirOrder.setDrugCost(payFee);
                    cirOrder.setMachinFee(BigDecimal.ZERO);
                    cirOrder.setTotalFee(payFee.add(order.getMachinFee()));
                    cirOrder.setExpressFee(BigDecimal.ZERO);
                    cirOrder.setActualCharge(cirOrder.getTotalFee().add(cirOrder.getExpressFee()));
                    cirOrder.setPayWay(6);
                    cirOrder.setCirulationCost(BigDecimal.ZERO);
                    cirOrder.setCirOrderNo(null);
                    cirOrder.setCirInfoNo(null);
                    cirOrder.setOrderNo(value.get(0).getOrderNo());
                    cirOrder.setPharmacyId(value.get(0).getPharmacyId());
                    cirOrders.add(cirOrder);

                    Message tempMessage = new Message();
                    tempMessage.setMessageId(cirOrder.getOrderNo());
                    tempMessage.setPharmacyId(cirOrder.getPharmacyId());
                    tempMessage.setMsgUrl("/ordermag/outorder?orderNo=" + cirOrder.getOrderNo());
                    tempMessage.setType(1);
                    String title = "饮片订单";
                    if (cirInfo.getPrescriptionType() == 2) {
                        title = "成药订单";
                    } else if (cirInfo.getPrescriptionType() == 3) {
                        title = "颗粒订单";
                    }
                    tempMessage.setTitle(cirOrder.getPatientName() + title + "<font color=\"#00FF00\">支付成功</font>，请及时处理");
                    messages.add(tempMessage);

                    //保存地址
                    if (!"-1".equals(expressCode)) {
                        OrderAddress temp = new OrderAddress();
                        BeanUtils.copyProperties(orderAddress, temp);
                        temp.setId(null);
                        temp.setOrderNo(cirOrder.getOrderNo());
                        orderAddressService.save(temp);
                    }


                    infoDrugService.saveBatch(value);
                }
                messageService.saveOrUpdateBatch(messages);
                infoService.saveBatch(cirInfos);
                this.saveBatch(cirOrders);

            }

            infoService.saveBatch(infos);
            consultService.save(consult);
            this.save(order);

            Message message = new Message();
            message.setMessageId(order.getOrderNo());
            message.setPharmacyId(order.getPharmacyId());
            message.setMsgUrl("/ordermag/outorder?orderNo=" + order.getOrderNo());
            message.setType(1);
            String title = "饮片订单";
            if (infos.get(0).getPrescriptionType() == 2) {
                title = "成药订单";
            } else if (infos.get(0).getPrescriptionType() == 3) {
                title = "颗粒订单";
            }
            message.setTitle(order.getPatientName() + title + "<font color=\"#00FF00\">支付成功</font>，请及时处理");
            messageService.save(message);

            response.put("status", "1");
            response.put("message", "成功");
            response.put("pst_items", list);
            return response;
        } catch (Exception e) {
            log.error("接收订单错误：{}", e);
            response.put("status", "0");
            response.put("message", e.getMessage());
            response.put("order_no", orderNo);
            return response;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> refundOrder(RefundOrderVO refundOrderVO, PrescriptionOrder order) {

        if (refundOrderVO.getType() == 2) {
            //全部退款
            List<Info> list = infoService.list(Wrappers.<Info>query().lambda().eq(Info::getOrderNo, refundOrderVO.getOrderNo()));
            return refundAll(refundOrderVO, list, order);
        } else {
            //部分退款
            return refundPart(refundOrderVO, order);
        }
    }

    /**
     * 订单收费
     *
     * @param criteria
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Object chargeOrder(ChargeOrderCriteria criteria) {
        Order order = this.getOne(Wrappers.<Order>query().lambda().eq(Order::getOrderNo, criteria.getOrderNo()));
        if (CharUtil.isEmpty(order)) {
            throw new ServiceException("订单不存在");
        }
        if (order.getPayStatus() == 4) {
            throw new ServiceException("订单已退费");
        }
        if (order.getPayStatus() != 0) {
            throw new ServiceException("订单已收费");
        }
        //邮寄
        if (criteria.getDeliveryType() == 1) {
//            if(criteria.getExpressFee()==null){
//                throw new ServiceException("邮寄费不能为空");
//            }
            if (CharUtil.isEmpty(criteria.getOrderAddress())
                    || CharUtil.isEmpty(criteria.getOrderAddress().getUsername())
                    || CharUtil.isEmpty(criteria.getOrderAddress().getPhone())
                    || CharUtil.isEmpty(criteria.getOrderAddress().getProvince())
                    || CharUtil.isEmpty(criteria.getOrderAddress().getCity())
                    || CharUtil.isEmpty(criteria.getOrderAddress().getArea())
                    || CharUtil.isEmpty(criteria.getOrderAddress().getAddress())) {
                throw new ServiceException("邮寄地址不能为空");
            }
            criteria.getOrderAddress().setPharmacyId(LoginUserUtil.getPharmId());
            criteria.getOrderAddress().setOrderNo(criteria.getOrderNo());
            orderAddressService.save(criteria.getOrderAddress());
        }

        //更新处方
        infoService.update(Wrappers.<Info>update().lambda().set(Info::getPayStatus, 1).set(Info::getOrderCondition, 1).eq(Info::getDeleteFlag, 0).eq(Info::getPayStatus, 0).ne(Info::getOrderCondition, 5).eq(Info::getOrderNo, order.getOrderNo()));
        //更新处方详情
        infoDrugService.update(Wrappers.<InfoDrug>update().lambda().set(InfoDrug::getStatus, 1).eq(InfoDrug::getStatus, 0).eq(InfoDrug::getDeleteFlag, 0).eq(InfoDrug::getOrderNo, order.getOrderNo()).eq(InfoDrug::getIsCancel, 0));
        //附加费用
//        prescriptionChargeService.update(Wrappers.<PrescriptionCharge>update().lambda().set(PrescriptionCharge::getStatus,1).eq(PrescriptionCharge::getStatus,0).eq(PrescriptionCharge::getOrderNo,order.getOrderNo()));

        Order ode = new Order();
        ode.setId(order.getId());
        ode.setDiffFee(criteria.getDiffFee() == null ? BigDecimal.ZERO : criteria.getDiffFee());
        ode.setDrugDiscount(criteria.getDrugDiscount() == null ? BigDecimal.ONE : criteria.getDrugDiscount().divide(BigDecimal.valueOf(100)));
        ode.setAllDiscount(criteria.getAllDiscount() == null ? BigDecimal.ONE : criteria.getAllDiscount().divide(BigDecimal.valueOf(100)));
        ode.setOtherFee(criteria.getOtherFee() == null ? BigDecimal.ZERO : criteria.getOtherFee());
        ode.setPayWay(criteria.getPayWay());
        ode.setPayTime(new Date());
        ode.setPayStatus(1);
        ode.setOrderCondition(1);
        ode.setDeliveryType(criteria.getDeliveryType());
//        实力收费=（药费总价×药费折扣+其他费用+加工费）×整体折扣-减免费用
//        BigDecimal actualCharge=order.getTotalFee().add(ode.getOtherFee()).multiply(ode.getAllDiscount()).subtract(order.getDrugCost().subtract(order.getDrugCost().multiply(ode.getDrugDiscount()))).subtract(ode.getDiffFee());
        BigDecimal actualCharge = (order.getDrugCost().multiply(ode.getDrugDiscount()).add(ode.getOtherFee()).add(order.getMachinFee())).multiply(ode.getAllDiscount()).subtract(ode.getDiffFee());
        BigDecimal drugCost = order.getDrugCost().multiply(ode.getDrugDiscount()).multiply(ode.getAllDiscount());
        if (criteria.getDeliveryType() == 1 && drugCost.compareTo(BigDecimal.valueOf(100)) == -1) {
            //实际收费小于100 邮费10块
            ode.setExpressFee(BigDecimal.TEN);
        } else {
            ode.setExpressFee(BigDecimal.ZERO);
        }
        //最终实际收费=实际收费+邮费
        ode.setActualCharge(ode.getExpressFee().add(actualCharge));
        this.updateById(ode);
        return true;
    }

    /**
     * @return void
     * @Author yzq
     * @Description 全部退款
     * @Date 2021/7/26 14:33
     * @Param [refundOrderVO, info, order]
     **/
    private ResponseEntity<Object> refundPart(RefundOrderVO refundOrderVO, PrescriptionOrder order) {
        if (CharUtil.isEmpty(refundOrderVO.getInfoList())) {
            throw new ServiceException("请填写处方退款列表");
        }
        JSONArray array = new JSONArray();
        //验证参数合法性
        for (RefundInfoVO refundInfo : refundOrderVO.getInfoList()) {
            if (CharUtil.isEmpty(refundInfo.getPstNo())) {
                throw new ServiceException("退款处方列表中处方号不能为空");
            }
            if (CharUtil.isEmpty(refundInfo.getType())) {
//                throw new ServiceException("处方号【"+refundInfo.getPstNo()+"】请输入退款方式");
                refundInfo.setType(2);//默认全部退款
            }
            //退款处方列表
            Info info = infoService.getOne(Wrappers.<Info>query().lambda().eq(Info::getInfoNo, refundInfo.getPstNo()));
            if (CharUtil.isEmpty(info)) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", "处方号【" + refundInfo.getPstNo() + "】不存在");
                array.add(jsonObject);
                continue;
            }
            if (2 != info.getPrescriptionType() && refundInfo.getType() == 1) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", "处方号【" + refundInfo.getPstNo() + "】属于非成药处方,不能部分退款");
                array.add(jsonObject);
                continue;
            }
            //部分退款验证药品
            if (refundInfo.getType() == 1) {
                for (RefundInfoDetailVO detailVO : refundInfo.getPstItems()) {
                    JSONObject jsonObject = new JSONObject();
                    if (CharUtil.isEmpty(detailVO.getRefundNum()) || CharUtil.isEmpty(detailVO.getDrugId())) {
                        throw new ServiceException("药品id和退款数量不能为空");
                    }
                    InfoDrug infoDrug = infoDrugService.getOne(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, info.getInfoNo())
                            .eq(InfoDrug::getDrugId, detailVO.getDrugId()));

                    //判断是否是流转药品
                    if (infoDrug.getIsCirulation() == 1) {
                        infoDrug = infoDrugService.getOne(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, infoDrug.getCirInfoNo()).eq(InfoDrug::getDrugId, infoDrug.getCirDrugId()));
                    }

                    if (CharUtil.isEmpty(infoDrug)) {
                        jsonObject.put("message", "处方【" + refundInfo.getPstNo() + "】中药品id:" + detailVO.getDrugId() + "不存在");
                        array.add(jsonObject);
                        continue;
                    }
                    Integer leftCount = infoDrug.getQuantity() - infoDrug.getRefundCount();
                    if (leftCount < detailVO.getRefundNum()) {
                        jsonObject.put("message", "处方【" + refundInfo.getPstNo() + "】中药品id：" + detailVO.getDrugId() + "退款个数大于剩余个数,剩余：" + leftCount);
                        array.add(jsonObject);
                        continue;
                    }
                }
            }
        }
        //验证不合法
        if (!CharUtil.isEmpty(array) && array.size() > 0) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("status", 2);
            jsonObject.put("message", "退款错误");
            jsonObject.put("data", array.toJSONString());
            return new ResponseEntity(jsonObject, HttpStatus.OK);
        }
        //开始退款
        String refundNo = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
        List<PrescriptionRefundDetail> list = new ArrayList<>();
        Map<String, BigDecimal> maps = new HashMap<>();
        for (RefundInfoVO refundInfo : refundOrderVO.getInfoList()) {
            Info info = infoService.getOne(Wrappers.<Info>query().lambda().eq(Info::getInfoNo, refundInfo.getPstNo()));
            //该处方 成药部分退款
            if (2 == info.getPrescriptionType() && 1 == refundInfo.getType()) {
                //成药处方，部分退款
                Map<String, String> infos = new HashMap<>();
                for (RefundInfoDetailVO detailVO : refundInfo.getPstItems()) {
                    //退款处方列表
                    InfoDrug infoDrug = infoDrugService.getOne(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, info.getInfoNo())
                            .eq(InfoDrug::getDrugId, detailVO.getDrugId()));
                    //药品流转
                    if (infoDrug.getIsCirulation() == 1) {
                        infoDrug = infoDrugService.getOne(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, infoDrug.getCirInfoNo()).eq(InfoDrug::getDrugId, infoDrug.getCirDrugId()));
                    }
                    PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
                    InfoDrug temp = new InfoDrug();
                    temp.setId(infoDrug.getId());
                    temp.setRefundCount(infoDrug.getRefundCount() + detailVO.getRefundNum());
                    if (temp.getRefundCount() >= infoDrug.getQuantity()) {
                        temp.setStatus(3);
                    } else {
                        temp.setStatus(2);
                    }
//                    temp.setRefundType(1);
                    temp.setOperateNum(infoDrug.getOperateNum() + detailVO.getRefundNum());
                    infoDrugService.updateById(temp);//修改详情

                    //未确认，退款，不需要操作库存
//                    if (order.getOrderCondition()!=1 && order.getOrderCondition()!=2) {
//                        refundDrugStock(infoDrug,detailVO.getRefundNum());
//                    }
                    //退款明细记录
                    prescriptionRefundDetail.setRefundNum(detailVO.getRefundNum());
                    prescriptionRefundDetail.setPharmacyId(infoDrug.getPharmacyId());
                    prescriptionRefundDetail.setBusinessId(infoDrug.getId().toString());
                    prescriptionRefundDetail.setProjectId(infoDrug.getDrugId().toString());
                    prescriptionRefundDetail.setName(infoDrug.getDrugName());
                    prescriptionRefundDetail.setRefund(infoDrug.getDiscountPrice().multiply(BigDecimal.valueOf(detailVO.getRefundNum())));
                    prescriptionRefundDetail.setRefundPrice(prescriptionRefundDetail.getRefund());
                    prescriptionRefundDetail.setRefundNo(refundNo);
                    prescriptionRefundDetail.setRefundType(1);
                    prescriptionRefundDetail.setOrderNo(infoDrug.getOrderNo());
                    prescriptionRefundDetail.setInfoNo(infoDrug.getInfoNo());
                    list.add(prescriptionRefundDetail);
                    BigDecimal tot = maps.get(infoDrug.getOrderNo());
                    if (tot == null) {
                        maps.put(infoDrug.getOrderNo(), prescriptionRefundDetail.getRefund());
                    } else {
                        maps.put(infoDrug.getOrderNo(), tot.add(prescriptionRefundDetail.getRefund()));
                    }
                    infos.put(infoDrug.getInfoNo(), "随便");
                }
                //流转药品处方修改处方状态 包含本订单（未流转）
                Iterator<Map.Entry<String, String>> iterator = infos.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, String> entry = iterator.next();
                    String infoNo = entry.getKey();
                    long count = infoDrugService.count(Wrappers.<InfoDrug>query().lambda().lt(InfoDrug::getStatus, 3).eq(InfoDrug::getDeleteFlag, 0).eq(InfoDrug::getInfoNo, infoNo).eq(InfoDrug::getIsCirulation, 0));
                    int status = 2;
                    if (count <= 0) {
                        status = 3;
                    }
                    infoService.update(Wrappers.<Info>update().lambda().set(Info::getPayStatus, status).eq(Info::getInfoNo, infoNo));
                }
            }
            //全部退款
            else {
                //全部退款  饮片/成药
                refundOneAll(maps, refundNo, list, info, order);
            }
        }

        prescriptionRefundDetailService.saveBatch(list);

        //处理订单状态包括流转金额
        Iterator<Map.Entry<String, BigDecimal>> iterator = maps.entrySet().iterator();
        while (iterator.hasNext()) {
            //订单属于全部退款还是部分退款
            //查找是否存在未审核的处方
            Map.Entry<String, BigDecimal> entry = iterator.next();
            PrescriptionOrder tempOrder = prescriptionService.getOne(Wrappers.<PrescriptionOrder>query().lambda().eq(PrescriptionOrder::getOrderNo, entry.getKey()));
            long count = infoService.count(Wrappers.<Info>query().lambda().lt(Info::getPayStatus, 3).eq(Info::getDeleteFlag, 0).eq(Info::getOrderNo, tempOrder.getOrderNo()));
            Integer payStatus = 3;
            if (count <= 0) {
                payStatus = 4;
            }
            PrescriptionOrder prescriptionOrder = new PrescriptionOrder();
            prescriptionOrder.setId(tempOrder.getId());
            prescriptionOrder.setPayStatus(payStatus);
            prescriptionOrder.setRefundFlag(1);
            this.updateById(prescriptionOrder);

            Info info = infoService.getOne(Wrappers.<Info>query().lambda().eq(Info::getDeleteFlag, 0).eq(Info::getOrderNo, tempOrder.getOrderNo()));
            Message message = new Message();
            message.setMessageId(tempOrder.getOrderNo());
            message.setPharmacyId(tempOrder.getPharmacyId());
            message.setMsgUrl("/ordermag/outorder?orderNo=" + tempOrder.getOrderNo());
            message.setType(1);
            String title = "饮片订单";
            if (info.getPrescriptionType() == 2) {
                title = "成药订单";
            } else if (info.getPrescriptionType() == 3) {
                title = "颗粒订单";
            }
            message.setTitle(tempOrder.getPatientName() + title + "<font color=\"#FF0000\">已部分退款</font>，请及时处理");
            messageService.save(message);


            //退款单记录
            PrescriptionRefund prescriptionRefund = new PrescriptionRefund();
            prescriptionRefund.setRefundNo(refundNo);
            prescriptionRefund.setRefundMsg(refundOrderVO.getMsg());
            prescriptionRefund.setOrderNo(tempOrder.getOrderNo());
            prescriptionRefund.setPharmacyId(tempOrder.getPharmacyId());
            prescriptionRefund.setRefund(entry.getValue());
            prescriptionRefund.setRefundPrice(entry.getValue());
            prescriptionRefund.setActRefund(BigDecimal.valueOf(Double.valueOf(refundOrderVO.getActRefund())));
            prescriptionRefund.setRefundTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", refundOrderVO.getRefundTime()));
            prescriptionRefundService.save(prescriptionRefund);

        }


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("status", "1");
        jsonObject.put("message", "退款成功");
        return new ResponseEntity(jsonObject, HttpStatus.OK);
    }


    /**
     * @return void
     * @Author yzq
     * @Description 订单全部退款（包含所有处方）
     * @Date 2021/7/26 14:33
     * @Param [refundOrderVO, info, order]
     **/
    private ResponseEntity<Object> refundAll(RefundOrderVO refundOrderVO, List<Info> infoList, PrescriptionOrder order) {
        refundOneOrderAll(refundOrderVO, infoList, order);
        //存在流转单
        if (!CharUtil.isEmpty(order.getCirOrderNo())) {
            //获取所有流转订单
            String[] orders = order.getCirOrderNo().split(",");
            for (String orderNo : orders) {
                PrescriptionOrder tempOrder = prescriptionService.getOne(Wrappers.<PrescriptionOrder>query().lambda().eq(PrescriptionOrder::getOrderNo, orderNo));
                //流转订单没有全部退款
                if (!CharUtil.isEmpty(tempOrder) && tempOrder.getPayStatus() != 4) {
                    List<Info> list = infoService.list(Wrappers.<Info>query().lambda().eq(Info::getOrderNo, tempOrder.getOrderNo()));
                    refundOneOrderAll(refundOrderVO, list, tempOrder);
                }
            }
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("status", "1");
        jsonObject.put("message", "退款成功");
        return new ResponseEntity(jsonObject, HttpStatus.OK);
    }

    /**
     * 一个订单退款全部
     *
     * @param refundOrderVO
     * @param infoList
     * @param order
     */
    private void refundOneOrderAll(RefundOrderVO refundOrderVO, List<Info> infoList, PrescriptionOrder order) {
        //全部退款
        BigDecimal total = BigDecimal.ZERO;
        String refundNo = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
        List<PrescriptionRefundDetail> list = new ArrayList<>();
        for (Info info : infoList) {
            //未流转的药品
            List<InfoDrug> infoDruglist = infoDrugService.list(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, info.getInfoNo()).eq(InfoDrug::getIsCirulation, 0));
            for (InfoDrug infoDrug : infoDruglist) {
                PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
                InfoDrug temp = new InfoDrug();
                temp.setId(infoDrug.getId());
                temp.setRefundCount(infoDrug.getQuantity() - infoDrug.getRefundCount());
                temp.setStatus(3);
//                    temp.setRefundType(1);
                temp.setOperateNum(infoDrug.getOperateNum() + infoDrug.getQuantity());
                infoDrugService.updateById(temp);//修改详情
                //未确认，退款，不需要操作库存 2:确认，3：部分退费，4：已退费
//                    if (order.getOrderCondition() != 1 && order.getOrderCondition() != 2) {
//                        refundDrugStock(infoDrug, null);
//                    }
                //退款明细记录
                prescriptionRefundDetail.setRefundNum(infoDrug.getQuantity() - infoDrug.getRefundCount());
                prescriptionRefundDetail.setPharmacyId(infoDrug.getPharmacyId());
                prescriptionRefundDetail.setBusinessId(infoDrug.getId().toString());
                prescriptionRefundDetail.setProjectId(infoDrug.getDrugId().toString());
                prescriptionRefundDetail.setName(infoDrug.getDrugName());
                prescriptionRefundDetail.setRefund(infoDrug.getDiscountPrice().multiply(BigDecimal.valueOf(infoDrug.getQuantity())));
                prescriptionRefundDetail.setRefundPrice(prescriptionRefundDetail.getRefund());
                prescriptionRefundDetail.setRefundNo(refundNo);
                prescriptionRefundDetail.setRefundType(1);
                prescriptionRefundDetail.setOrderNo(infoDrug.getOrderNo());
                prescriptionRefundDetail.setInfoNo(infoDrug.getInfoNo());
                list.add(prescriptionRefundDetail);
                total = total.add(prescriptionRefundDetail.getRefund());
            }
            infoService.update(Wrappers.<Info>update().lambda().set(Info::getPayStatus, 3).eq(Info::getInfoNo, info.getInfoNo()));
        }
        //订单退款
        PrescriptionOrder prescriptionOrder = new PrescriptionOrder();
        prescriptionOrder.setId(order.getId());
        prescriptionOrder.setPayStatus(4);
        prescriptionOrder.setRefundFlag(1);
        this.updateById(prescriptionOrder);

        Message message = new Message();
        message.setMessageId(order.getOrderNo());
        message.setPharmacyId(order.getPharmacyId());
        message.setMsgUrl("/ordermag/outorder?orderNo=" + order.getOrderNo());
        message.setType(1);
        String title = "饮片订单";
        if (infoList.get(0).getPrescriptionType() == 2) {
            title = "成药订单";
        } else if (infoList.get(0).getPrescriptionType() == 3) {
            title = "颗粒订单";
        }
        message.setTitle(order.getPatientName() + title + "<font color=\"#FF0000\">已全部退款</font>，请及时处理");
        messageService.save(message);

        //退款单记录
        PrescriptionRefund prescriptionRefund = new PrescriptionRefund();
        prescriptionRefund.setRefundNo(refundNo);
        prescriptionRefund.setRefundMsg(refundOrderVO.getMsg());
        prescriptionRefund.setOrderNo(order.getOrderNo());
        prescriptionRefund.setPharmacyId(order.getPharmacyId());
        prescriptionRefund.setRefund(total);
        prescriptionRefund.setRefundPrice(total);
        prescriptionRefund.setActRefund(BigDecimal.valueOf(Double.valueOf(refundOrderVO.getActRefund())));
        prescriptionRefund.setRefundTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", refundOrderVO.getRefundTime()));
        prescriptionRefundService.save(prescriptionRefund);
        prescriptionRefundDetailService.saveBatch(list);

    }

    /**
     * 退款退库存
     *
     * @param infoDrug
     * @param refundNum
     */
    private void refundDrugStock(InfoDrug infoDrug, Integer refundNum) {
        List<OrderComfire> orderComfireList = orderComfireService.list(Wrappers.<OrderComfire>query().lambda()
                .eq(OrderComfire::getInfoDrugId, infoDrug.getId()).gt(OrderComfire::getPlusNum, 0));
        int count = infoDrug.getQuantity();
        if (!CharUtil.isEmpty(refundNum)) {
            count = refundNum;
        }
        int tempcount = count;
        for (OrderComfire oc : orderComfireList) {
            OrderComfire orderComfire = new OrderComfire();
            orderComfire.setId(oc.getId());
            orderComfire.setInfoDrugId(infoDrug.getId());
            orderComfire.setWarehousingId(oc.getWarehousingId());
            DrugWareHousingDetail det = drugWareHousingDetailService.getById(oc.getWarehousingId());
            //顺位第一个入库大于扣减个数
            if (oc.getPlusNum() >= count) {
                DrugWareHousingDetail detail = new DrugWareHousingDetail();
                detail.setId(oc.getWarehousingId());
                detail.setLeftCount(det.getLeftCount() + count);
                drugWareHousingDetailService.updateById(detail);
                orderComfire.setPlusNum(oc.getPlusNum() - count);
                count = 0;
                orderComfireService.updateById(orderComfire);
                break;
            } else {
                //顺位第一个入库小于扣减个数
                count = count - oc.getPlusNum();
                DrugWareHousingDetail detail = new DrugWareHousingDetail();
                detail.setId(oc.getWarehousingId());
                detail.setLeftCount(det.getLeftCount() + oc.getPlusNum());
                drugWareHousingDetailService.updateById(detail);
                orderComfire.setPlusNum(0);
                orderComfireService.updateById(orderComfire);
            }

        }
        //修改库存
        Drug drug = drugService.getById(infoDrug.getDrugId());
        Drug tempDrug = new Drug();
        tempDrug.setId(infoDrug.getDrugId());
        tempDrug.setStock(drug.getStock() + tempcount);
        drugService.updateById(tempDrug);
    }


    /**
     * 退款退库存
     *
     * @param infoDrug
     * @param refundNum
     */
    private void refundLocalDrugStock(InfoDrug infoDrug, Integer refundNum) {
        List<OrderComfire> orderComfireList = orderComfireService.list(Wrappers.<OrderComfire>query().lambda()
                .eq(OrderComfire::getInfoDrugId, infoDrug.getId()).gt(OrderComfire::getPlusNum, 0));
        int count = infoDrug.getQuantity();
        if (!CharUtil.isEmpty(refundNum)) {
            count = refundNum;
        }
        int tempcount = count;
        for (OrderComfire oc : orderComfireList) {
            OrderComfire orderComfire = new OrderComfire();
            orderComfire.setId(oc.getId());
            orderComfire.setInfoDrugId(infoDrug.getId());
            orderComfire.setWarehousingId(oc.getWarehousingId());
            DrugWareHousingDetail det = drugWareHousingDetailService.getById(oc.getWarehousingId());
            //顺位第一个入库大于扣减个数
            if (oc.getPlusNum() >= count) {
                DrugWareHousingDetail detail = new DrugWareHousingDetail();
                detail.setId(oc.getWarehousingId());
                detail.setLeftCount(det.getLeftCount() + count);
                drugWareHousingDetailService.updateById(detail);
                orderComfire.setPlusNum(oc.getPlusNum() - count);
                count = 0;
                orderComfireService.updateById(orderComfire);
                break;
            } else {
                //顺位第一个入库小于扣减个数
                count = count - oc.getPlusNum();
                DrugWareHousingDetail detail = new DrugWareHousingDetail();
                detail.setId(oc.getWarehousingId());
                detail.setLeftCount(det.getLeftCount() + oc.getPlusNum());
                drugWareHousingDetailService.updateById(detail);
                orderComfire.setPlusNum(0);
                orderComfireService.updateById(orderComfire);
            }

        }

        //修改库存
        Drug drug = drugService.getById(infoDrug.getDrugId());
        Drug tempDrug = new Drug();
        tempDrug.setId(infoDrug.getDrugId());
        tempDrug.setStock(drug.getStock() + tempcount);
        drugService.updateById(tempDrug);
    }


    /**
     * @return void
     * @Author yzq
     * @Description 单个处方全部退款
     * @Date 2021/8/23 16:04
     * @Param [total, refundNo, list, info, order]
     **/
    private Map<String, BigDecimal> refundOneAll(Map<String, BigDecimal> maps, String refundNo, List<PrescriptionRefundDetail> list, Info info, PrescriptionOrder order) {
        //全部退款
        List<InfoDrug> infoDruglist = infoDrugService.list(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, info.getInfoNo()));
        Map<String, String> infos = new HashMap<>();
        for (InfoDrug infoDrug : infoDruglist) {
            if (infoDrug.getIsCirulation() == 1) {
                infoDrug = infoDrugService.getOne(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, infoDrug.getCirInfoNo()).eq(InfoDrug::getDrugId, infoDrug.getCirDrugId()));
            }
            PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
            InfoDrug temp = new InfoDrug();
            temp.setId(infoDrug.getId());
            temp.setRefundCount(infoDrug.getQuantity());
            temp.setStatus(3);
//                temp.setRefundType(1);
            temp.setOperateNum(infoDrug.getOperateNum() + infoDrug.getQuantity());
            infoDrugService.updateById(temp);//修改详情
            //未确认，退款，不需要操作库存 2:确认，3：部分退费，4：已退费
//                if(order.getOrderCondition()!=1&&order.getOrderCondition()!=2) {
//                    refundDrugStock(infoDrug, null);
//                }
            //退款明细记录
            prescriptionRefundDetail.setRefundNum(infoDrug.getQuantity());
            prescriptionRefundDetail.setPharmacyId(infoDrug.getPharmacyId());
            prescriptionRefundDetail.setBusinessId(infoDrug.getId().toString());
            prescriptionRefundDetail.setProjectId(infoDrug.getDrugId().toString());
            prescriptionRefundDetail.setName(infoDrug.getDrugName());
            prescriptionRefundDetail.setRefund(infoDrug.getDiscountPrice().multiply(BigDecimal.valueOf(infoDrug.getQuantity())));
            prescriptionRefundDetail.setRefundPrice(prescriptionRefundDetail.getRefund());
            prescriptionRefundDetail.setRefundNo(refundNo);
            prescriptionRefundDetail.setRefundType(1);
            prescriptionRefundDetail.setOrderNo(infoDrug.getOrderNo());
            prescriptionRefundDetail.setInfoNo(infoDrug.getInfoNo());
            list.add(prescriptionRefundDetail);
            BigDecimal tot = maps.get(infoDrug.getOrderNo());
            if (tot == null) {
                maps.put(infoDrug.getOrderNo(), prescriptionRefundDetail.getRefund());
            } else {
                maps.put(infoDrug.getOrderNo(), tot.add(prescriptionRefundDetail.getRefund()));
            }
            infos.put(infoDrug.getInfoNo(), "随便");
        }
//            infoService.update(Wrappers.<Info>update().lambda().set(Info::getPayStatus,3).eq(Info::getInfoNo,info.getInfoNo()));
        //流转药品处方修改处方状态 包含本订单（未流转）
        Iterator<Map.Entry<String, String>> iterator = infos.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            String infoNo = entry.getKey();
            long count = infoDrugService.count(Wrappers.<InfoDrug>query().lambda().lt(InfoDrug::getStatus, 3).eq(InfoDrug::getDeleteFlag, 0).eq(InfoDrug::getInfoNo, infoNo).eq(InfoDrug::getIsCirulation, 0));
            int status = 2;
            if (count <= 0) {
                status = 3;
            }
            infoService.update(Wrappers.<Info>update().lambda().set(Info::getPayStatus, status).eq(Info::getInfoNo, infoNo));
        }
        return maps;
    }


    /**
     * 调剂订单
     *
     * @param list
     * @param tempOrder
     * @param info
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void confirmOrder(List<InfoDrug> list, Order tempOrder, Info info) {
        String errorMsg = "";
        List<String> drugNames = new ArrayList<>();
        for (InfoDrug infoDrug : list) {
            Drug drug = drugService.getOne(Wrappers.<Drug>query().lambda().eq(Drug::getId, infoDrug.getDrugId()).eq(Drug::getStatus, 0));
            if (CharUtil.isEmpty(drug)) {
                errorMsg = errorMsg + "" + infoDrug.getDrugName() + "不存在,或已被下架;";
                continue;
            }
            if (CharUtil.isEmpty(drug.getStock())) {
                drug.setStock(0);
            }
            infoDrug.setQuantity(infoDrug.getQuantity() - infoDrug.getRefundCount());//扣除已退个数
            if (infoDrug.getQuantity() > drug.getStock()) {
                errorMsg = errorMsg + infoDrug.getDrugName() + "库存不足;";
                continue;
            }
            //修改入库批次数量
            //获取有效期内，库存大于0的  按有效期升序排序
            //使用包装单位
            if (infoDrug.getUseUnit().equals(infoDrug.getPackUnit())) {
                int quantity = infoDrug.getQuantity();//包装单位数量
                if (quantity > 0) {
                    List<DrugWareHousingDetail> drugWareHousingDetailList = drugWareHousingDetailService.queryComfireList(drug.getId());
                    for (DrugWareHousingDetail drugWareHousingDetail : drugWareHousingDetailList) {
                        OrderComfire orderComfire = new OrderComfire();
                        orderComfire.setInfoDrugId(infoDrug.getId());
                        orderComfire.setWarehousingId(drugWareHousingDetail.getId());
                        orderComfire.setUseUnit(drug.getPackageUnit());
                        //顺位第一个入库大于扣减个数
                        if (drugWareHousingDetail.getLeftCount() >= quantity) {
                            DrugWareHousingDetail detail = new DrugWareHousingDetail();
                            detail.setId(drugWareHousingDetail.getId());
                            detail.setLeftCount(drugWareHousingDetail.getLeftCount() - quantity);
                            drugWareHousingDetailService.updateById(detail);
                            orderComfire.setDiveNum(quantity);
                            quantity = 0;
                        } else {
                            //顺位第一个入库小于扣减个数
                            quantity = quantity - drugWareHousingDetail.getLeftCount();
                            DrugWareHousingDetail detail = new DrugWareHousingDetail();
                            detail.setId(drugWareHousingDetail.getId());
                            detail.setLeftCount(0);
                            drugWareHousingDetailService.updateById(detail);
                            orderComfire.setDiveNum(drugWareHousingDetail.getLeftCount());
                        }

                        orderComfire.setPlusNum(orderComfire.getDiveNum());
                        orderComfireService.save(orderComfire);
                        if (quantity <= 0) {
                            break;
                        }
                    }
                    if (quantity > 0) {
                        errorMsg = errorMsg + infoDrug.getDrugName() + "库存不足;";
                        continue;
                    } else {
                        //修改月使用数
                        drugService.updateMothUseById(drug.getId(), infoDrug.getQuantity(), 0);
                        //出库修改药品数量
                        Drug tempDrug = new Drug();
                        tempDrug.setId(drug.getId());
                        tempDrug.setStock(drug.getStock() - infoDrug.getQuantity());
                        drugService.updateById(tempDrug);
                        //接近预警值
                        if (tempDrug.getStock() <= drug.getStockWarning()) {
                            drugNames.add(drug.getDrugName());
                        }
                    }
                }
            } else if (infoDrug.getUseUnit().equals(infoDrug.getTotalDoseUnit())) {
                //剂量单位
                int minquantity = infoDrug.getMinQuantity() - infoDrug.getRefundCount();//剂量单位数量减去扣除数量
                //剂量单位扣除
                //获取剂量单位剩余列表
                List<DrugWareHousingDetail> drugWareHousingDetailList = drugWareHousingDetailService.queryComfireList(drug.getId());
                //拆分剂量单位数量扣除
                for (DrugWareHousingDetail drugWareHousingDetail : drugWareHousingDetailList) {
                    OrderComfire orderComfire = new OrderComfire();
                    orderComfire.setInfoDrugId(infoDrug.getId());
                    orderComfire.setWarehousingId(drugWareHousingDetail.getId());
                    orderComfire.setUseUnit(drug.getTotalDoseUnit());
                    //顺位第一个入库大于扣减个数
                    if (drugWareHousingDetail.getMinLeftCount() >= minquantity) {
                        DrugWareHousingDetail detail = new DrugWareHousingDetail();
                        detail.setId(drugWareHousingDetail.getId());
                        detail.setMinLeftCount(drugWareHousingDetail.getMinLeftCount() - minquantity);

                        drugWareHousingDetailService.updateById(detail);
                        orderComfire.setDiveNum(minquantity);
                        minquantity = 0;
                    } else {
                        //顺位第一个入库小于扣减个数
                        minquantity = minquantity - drugWareHousingDetail.getMinLeftCount();
                        DrugWareHousingDetail detail = new DrugWareHousingDetail();
                        detail.setId(drugWareHousingDetail.getId());
                        detail.setMinLeftCount(0);
                        drugWareHousingDetailService.updateById(detail);
                        orderComfire.setDiveNum(drugWareHousingDetail.getLeftCount());
                    }
                    orderComfire.setPlusNum(orderComfire.getDiveNum());
                    orderComfireService.save(orderComfire);
                    if (minquantity <= 0) {
                        break;
                    }
                }
                if (minquantity > 0) {
                    //剂量单位数量不够，从包装单位拆分补足
                    List<DrugWareHousingDetail> detailList = drugWareHousingDetailService.queryComfireList(drug.getId());
                    for (DrugWareHousingDetail drugWareHousingDetail : detailList) {
                        OrderComfire orderComfire = new OrderComfire();
                        orderComfire.setInfoDrugId(infoDrug.getId());
                        orderComfire.setWarehousingId(drugWareHousingDetail.getId());
                        orderComfire.setUseUnit(drug.getTotalDoseUnit());
                        //顺位第一个入库大于扣减个数
                        int minCount = drugWareHousingDetail.getLeftCount() * drug.getTotalDose();
                        if (minCount >= minquantity) {
                            int minLeftCount = minCount - minquantity;
                            int leftCount = (int) Math.floor(Double.valueOf(minLeftCount) / Double.valueOf(drug.getTotalDose()));
                            DrugWareHousingDetail detail = new DrugWareHousingDetail();
                            detail.setId(drugWareHousingDetail.getId());
                            detail.setLeftCount(leftCount);
                            detail.setMinLeftCount(minLeftCount - (leftCount * drug.getTotalDose()));
                            drugWareHousingDetailService.updateById(detail);
                            orderComfire.setDiveNum(minquantity);
                            minquantity = 0;
                        } else {
                            //顺位第一个入库小于扣减个数
                            minquantity = minquantity - minCount;
                            DrugWareHousingDetail detail = new DrugWareHousingDetail();
                            detail.setId(drugWareHousingDetail.getId());
                            detail.setLeftCount(0);
                            drugWareHousingDetailService.updateById(detail);
                            orderComfire.setDiveNum(drugWareHousingDetail.getLeftCount());
                        }
                        orderComfire.setPlusNum(orderComfire.getDiveNum());
                        orderComfireService.save(orderComfire);
                        if (minquantity <= 0) {
                            break;
                        }

                    }

                }
                if (minquantity > 0) {
                    errorMsg = errorMsg + infoDrug.getDrugName() + "库存不足;";
                    continue;
                } else {
                    drugService.updateMothUseById(drug.getId(), 0, infoDrug.getMinQuantity());//修改月使用数
                    //出库修改药品数量
                    drugService.updateStockById(drug.getId());
                    Drug temDrug = drugService.getById(drug.getId());
                    if (temDrug.getStock() <= temDrug.getStockWarning()) {
                        drugNames.add(drug.getDrugName());
                    }

                }

            } else {
                throw new ServiceException("处方药品使用错误");
            }
        }
        // 返回204,药品错误列表
        if (!CharUtil.isEmpty(errorMsg)) {
            throw new ServiceException(errorMsg);
        }
        //订单调剂 订单不为空，订单调剂
        if (!CharUtil.isEmpty(tempOrder)) {
            PrescriptionOrder prescriptionOrder = new PrescriptionOrder();
            prescriptionOrder.setId(tempOrder.getId());
            prescriptionOrder.setOrderCondition(3);
            prescriptionOrder.setAdjustUserId(SecurityUtils.getUserId().toString());
            prescriptionOrder.setAdjustUser(LoginUserUtil.getNickName());
            prescriptionOrder.setAdjustTime(new Date());
            this.updateById(prescriptionOrder);

            //调剂中，未删除的处方，修改成已完成  调剂中==》已完成
            infoService.update(
                    Wrappers.<Info>update().lambda().set(Info::getOrderCondition, 3).set(Info::getAdjustUserId, prescriptionOrder.getAdjustUserId())
                            .set(Info::getAdjustUser, prescriptionOrder.getAdjustUser()).set(Info::getAdjustTime, new Date()).eq(Info::getDeleteFlag, 0).eq(Info::getOrderCondition, 2)
            );

        } else {
            //处方调剂
            Info tempInfo = new Info();
            tempInfo.setId(info.getId());
            tempInfo.setOrderCondition(3);
            tempInfo.setAdjustUserId(SecurityUtils.getUserId().toString());
            tempInfo.setAdjustUser(LoginUserUtil.getNickName());
            tempInfo.setAdjustTime(new Date());
            infoService.updateById(tempInfo);
            //查询调剂中，待审放个数
            long count = infoService.count(Wrappers.<Info>query().lambda().eq(Info::getDeleteFlag, 0).eq(Info::getOrderNo, info.getOrderNo()).and(
                    wrapper -> wrapper.eq(Info::getOrderCondition, 1).or().eq(Info::getOrderCondition, 2)
            ));
            //不存在，修改订单状态
            if (count <= 0) {
                this.update(Wrappers.<Order>update().lambda().set(Order::getOrderCondition, 3)
                        .set(Order::getAdjustUserId, SecurityUtils.getUserId().toString()).set(Order::getAdjustUser, LoginUserUtil.getNickName())
                        .set(Order::getAdjustTime, new Date()).eq(Order::getOrderNo, info.getOrderNo()));
            }
        }
        if (!CharUtil.isEmpty(drugNames) && drugNames.size() > 0) {
            sendMsg(drugNames);
        }
    }


    public void sendMsg(List<String> drugNames) {
        String profiles = SpringContextHolder.getActiveProfile();
        Store store = storeService.getById(LoginUserUtil.getPharmId());
        String message = "his-" + store.getStoreName() + "\n以下药品接近预警值:\n";
        for (String str : drugNames) {
            message = message + str + "\n";
        }
        if ("prod".equals(profiles)) {
            String url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=3d055bf6-e470-4c51-90a7-828d4970796b";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("msgtype", "text");
            JSONObject text = new JSONObject();
            text.put("content", message);
            jsonObject.put("text", text);
            String result = ConnectionUrlUtil.sendJsonPost(url, jsonObject.toJSONString());
            log.info(result);
        }
    }

    /**
     * 本地单退款
     *
     * @param refundOrderDto
     * @param order
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseEntity<Object> refundLocalOrder(RefundOrderDto refundOrderDto, Order order) {
        if (refundOrderDto.getRefundType() == 1) {
            //退全款
            List<Info> list = infoService.list(Wrappers.<Info>query().lambda().eq(Info::getOrderNo, refundOrderDto.getOrderNo()).eq(Info::getDeleteFlag, 0));
            return refundLocalAll(refundOrderDto, list, order);
        } else if (refundOrderDto.getRefundType() == 0) {
            //部分退款
            return refundLocalPartAll(refundOrderDto, order);
        } else {
            throw new ServiceException("退款类型错误");
        }
    }

    /**
     * 本地订单全部退款
     *
     * @param refundOrderDto
     * @param infoList
     * @param order
     * @return
     */
    private ResponseEntity<Object> refundLocalAll(RefundOrderDto refundOrderDto, List<Info> infoList, Order order) {
        //全部退款
        BigDecimal total = BigDecimal.ZERO;
        BigDecimal noTotal = BigDecimal.ZERO;
        String refundNo = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
        List<PrescriptionRefundDetail> list = new ArrayList<>();
        for (Info info : infoList) {
            //退处方列表
            List<InfoDrug> infoDruglist = infoDrugService.list(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, info.getInfoNo()));
            for (InfoDrug infoDrug : infoDruglist) {
                PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
                InfoDrug temp = new InfoDrug();
                temp.setId(infoDrug.getId());
                temp.setRefundCount(infoDrug.getQuantity());
                temp.setStatus(3);
                temp.setOperateNum(0);
                temp.setRefundType(refundOrderDto.getType());
                //退库存，且 已调剂完成
                if (refundOrderDto.getType() == 1 && (info.getOrderCondition() == 4 || info.getOrderCondition() == 3)) {
                    refundLocalDrugStock(infoDrug, null);
                    temp.setRefundType(1);
                }
                infoDrugService.updateById(temp);//修改详情
                //退款明细记录
                prescriptionRefundDetail.setRefundNum(infoDrug.getQuantity());
                prescriptionRefundDetail.setPharmacyId(infoDrug.getPharmacyId());
                prescriptionRefundDetail.setBusinessId(infoDrug.getId().toString());
                prescriptionRefundDetail.setProjectId(infoDrug.getDrugId().toString());
                prescriptionRefundDetail.setName(infoDrug.getDrugName());
                prescriptionRefundDetail.setRefund(infoDrug.getDiscountPrice().multiply(BigDecimal.valueOf(infoDrug.getQuantity())));
                prescriptionRefundDetail.setRefundPrice(prescriptionRefundDetail.getRefund().multiply(order.getDrugDiscount()).multiply(order.getAllDiscount()));
                prescriptionRefundDetail.setRefundNo(refundNo);
                prescriptionRefundDetail.setRefundType(1);
                prescriptionRefundDetail.setOrderNo(infoDrug.getOrderNo());
                prescriptionRefundDetail.setInfoNo(infoDrug.getInfoNo());
                list.add(prescriptionRefundDetail);
                total = total.add(prescriptionRefundDetail.getRefundPrice());
                noTotal = noTotal.add(prescriptionRefundDetail.getRefund());
            }
            //有药材加工费
            if (info.getProcessCost() != null && info.getProcessCost().compareTo(BigDecimal.ZERO) == 1) {
                //退药材加工费
                PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
                prescriptionRefundDetail.setRefundNum(1);
                prescriptionRefundDetail.setPharmacyId(order.getPharmacyId());
                prescriptionRefundDetail.setBusinessId(info.getId().toString());
                prescriptionRefundDetail.setProjectId("3");
                prescriptionRefundDetail.setName("药材加工费");
                prescriptionRefundDetail.setRefund(info.getProcessCost());
                prescriptionRefundDetail.setRefundPrice(info.getProcessCost().multiply(order.getAllDiscount()));
                prescriptionRefundDetail.setRefundNo(refundNo);
                prescriptionRefundDetail.setRefundType(3);
                prescriptionRefundDetail.setOrderNo(order.getOrderNo());
                prescriptionRefundDetail.setInfoNo(info.getInfoNo());
                list.add(prescriptionRefundDetail);
                total = total.add(prescriptionRefundDetail.getRefundPrice());
                noTotal = noTotal.add(prescriptionRefundDetail.getRefund());
            }

            //修改处方状态
            infoService.update(Wrappers.<Info>update().lambda().set(Info::getPayStatus, 3).eq(Info::getInfoNo, info.getInfoNo()));
        }

        //退邮费
        if (order.getExpressFee() != null && order.getExpressFee().compareTo(BigDecimal.ZERO) == 1) {
            //退药材加工费
            PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
            prescriptionRefundDetail.setRefundNum(1);
            prescriptionRefundDetail.setPharmacyId(order.getPharmacyId());
            prescriptionRefundDetail.setBusinessId(order.getId().toString());
            prescriptionRefundDetail.setProjectId("4");
            prescriptionRefundDetail.setName("邮寄费");
            prescriptionRefundDetail.setRefund(order.getExpressFee());
            prescriptionRefundDetail.setRefundPrice(order.getExpressFee());
            prescriptionRefundDetail.setRefundNo(refundNo);
            prescriptionRefundDetail.setRefundType(4);
            prescriptionRefundDetail.setOrderNo(order.getOrderNo());
            list.add(prescriptionRefundDetail);
            total = total.add(order.getExpressFee());
            noTotal = noTotal.add(order.getExpressFee());
        }
        //退其他费用
        if (order.getOtherFee() != null && order.getOtherFee().compareTo(BigDecimal.ZERO) == 1) {
            //退药材加工费
            PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
            prescriptionRefundDetail.setRefundNum(1);
            prescriptionRefundDetail.setPharmacyId(order.getPharmacyId());
            prescriptionRefundDetail.setBusinessId(order.getId().toString());
            prescriptionRefundDetail.setProjectId("5");
            prescriptionRefundDetail.setName("其他费用");
            prescriptionRefundDetail.setRefund(order.getOtherFee());
            prescriptionRefundDetail.setRefundPrice(order.getOtherFee().multiply(order.getAllDiscount()));
            prescriptionRefundDetail.setRefundNo(refundNo);
            prescriptionRefundDetail.setRefundType(5);
            prescriptionRefundDetail.setOrderNo(order.getOrderNo());
            list.add(prescriptionRefundDetail);
            total = total.add(prescriptionRefundDetail.getRefundPrice());
            noTotal = noTotal.add(prescriptionRefundDetail.getRefundPrice());
        }

        PrescriptionOrder prescriptionOrder = new PrescriptionOrder();
        prescriptionOrder.setId(order.getId());
        prescriptionOrder.setPayStatus(4);
        prescriptionOrder.setRefundFlag(2);
        this.updateById(prescriptionOrder);
        //退款单记录
        PrescriptionRefund prescriptionRefund = new PrescriptionRefund();
        prescriptionRefund.setRefundNo(refundNo);
        prescriptionRefund.setRefundMsg(refundOrderDto.getMsg());
        prescriptionRefund.setOrderNo(order.getOrderNo());
        prescriptionRefund.setPharmacyId(order.getPharmacyId());
        prescriptionRefund.setRefund(noTotal);
        prescriptionRefund.setRefundPrice(total);
        prescriptionRefund.setActRefund(total);
        prescriptionRefund.setRefundTime(new Date());
        prescriptionRefundService.save(prescriptionRefund);
        prescriptionRefundDetailService.saveBatch(list);
//        JSONObject jsonObject=new JSONObject();
//        jsonObject.put("status","1");
//        jsonObject.put("message","退款成功");
        return new ResponseEntity(true, HttpStatus.OK);
    }


    /**
     * 本地订单部分退款
     *
     * @param refundOrderDto
     * @param order
     * @return
     */
    private ResponseEntity<Object> refundLocalPartAll(RefundOrderDto refundOrderDto, Order order) {
        //全部退款
        BigDecimal total = BigDecimal.ZERO;
        BigDecimal noTotal = BigDecimal.ZERO;
        String refundNo = DateUtils.dateTimeNow() + RandomUtils.getRandomNumbers(6);
        List<PrescriptionRefundDetail> list = new ArrayList<>();
        for (String infoNo : refundOrderDto.getInfoIds()) {
            //退邮寄
            if ("1".equals(infoNo)) {
                //退邮费
                if (order.getExpressFee() != null && order.getExpressFee().compareTo(BigDecimal.ZERO) == 1) {
                    //退邮费
                    PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
                    prescriptionRefundDetail.setRefundNum(1);
                    prescriptionRefundDetail.setPharmacyId(order.getPharmacyId());
                    prescriptionRefundDetail.setBusinessId(order.getId().toString());
                    prescriptionRefundDetail.setProjectId("4");
                    prescriptionRefundDetail.setName("邮寄费");
                    prescriptionRefundDetail.setRefund(order.getExpressFee());
                    prescriptionRefundDetail.setRefundPrice(order.getExpressFee());
                    prescriptionRefundDetail.setRefundNo(refundNo);
                    prescriptionRefundDetail.setRefundType(4);
                    prescriptionRefundDetail.setOrderNo(order.getOrderNo());
                    list.add(prescriptionRefundDetail);
                    total = total.add(order.getExpressFee());
                    noTotal = noTotal.add(order.getExpressFee());
                } else {
                    throw new ServiceException("邮寄费为0,不能退");
                }

            } else if ("2".equals(infoNo)) {
                //退其他费用
                if (order.getOtherFee() != null && order.getOtherFee().compareTo(BigDecimal.ZERO) == 1) {
                    //退其他费用
                    PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
                    prescriptionRefundDetail.setRefundNum(1);
                    prescriptionRefundDetail.setPharmacyId(order.getPharmacyId());
                    prescriptionRefundDetail.setBusinessId(order.getId().toString());
                    prescriptionRefundDetail.setProjectId("5");
                    prescriptionRefundDetail.setName("其他费用");
                    prescriptionRefundDetail.setRefund(order.getOtherFee());
                    prescriptionRefundDetail.setRefundPrice(order.getOtherFee().multiply(order.getAllDiscount()));
                    prescriptionRefundDetail.setRefundNo(refundNo);
                    prescriptionRefundDetail.setRefundType(5);
                    prescriptionRefundDetail.setOrderNo(order.getOrderNo());
                    list.add(prescriptionRefundDetail);
                    total = total.add(prescriptionRefundDetail.getRefundPrice());
                    noTotal = noTotal.add(prescriptionRefundDetail.getRefund());
                } else {
                    throw new ServiceException("其他费用为0,不能退");
                }
            } else {
                //退处方
                Info info = infoService.getOne(Wrappers.<Info>query().lambda().eq(Info::getInfoNo, infoNo).eq(Info::getDeleteFlag, 0));
                if (CharUtil.isEmpty(info)) {
                    throw new ServiceException("处方【" + infoNo + "】不存在");
                }
                if (info.getPayStatus() == 0) {
                    throw new ServiceException("处方【" + infoNo + "】未支付,不能退款");
                }
                if (info.getPayStatus() == 3) {
                    throw new ServiceException("处方【" + infoNo + "】订单已退费,不能退款");
                }

                //修改处方状态
                infoService.update(Wrappers.<Info>update().lambda().set(Info::getPayStatus, 3).eq(Info::getInfoNo, info.getInfoNo()));
                //退处方列表
                List<InfoDrug> infoDruglist = infoDrugService.list(Wrappers.<InfoDrug>query().lambda().eq(InfoDrug::getInfoNo, info.getInfoNo()).eq(InfoDrug::getDeleteFlag, 0));
                for (InfoDrug infoDrug : infoDruglist) {
                    PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
                    InfoDrug temp = new InfoDrug();
                    temp.setId(infoDrug.getId());
                    temp.setRefundCount(infoDrug.getQuantity());
                    temp.setStatus(3);
                    temp.setRefundType(refundOrderDto.getType());
                    temp.setOperateNum(0);
                    //退库存，且 已调剂完成
                    if (refundOrderDto.getType() == 1 && (info.getOrderCondition() == 4 || info.getOrderCondition() == 3)) {
                        List<OrderComfire> orderComfireList = orderComfireService.list(Wrappers.<OrderComfire>query().lambda()
                                .eq(OrderComfire::getInfoDrugId, infoDrug.getId()).gt(OrderComfire::getPlusNum, 0));
                        temp.setRefundType(1);
                        int count = infoDrug.getQuantity();
                        for (OrderComfire oc : orderComfireList) {
                            OrderComfire orderComfire = new OrderComfire();
                            orderComfire.setId(oc.getId());
                            orderComfire.setInfoDrugId(infoDrug.getId());
                            orderComfire.setWarehousingId(oc.getWarehousingId());
                            DrugWareHousingDetail det = drugWareHousingDetailService.getById(oc.getWarehousingId());
                            //顺位第一个入库大于扣减个数
                            if (oc.getPlusNum() >= count) {
                                DrugWareHousingDetail detail = new DrugWareHousingDetail();
                                detail.setId(oc.getWarehousingId());
                                detail.setLeftCount(det.getLeftCount() + count);
                                drugWareHousingDetailService.updateById(detail);
                                orderComfire.setPlusNum(oc.getPlusNum() - count);
                                count = 0;
                                orderComfireService.updateById(orderComfire);
                                break;
                            } else {
                                //顺位第一个入库小于扣减个数
                                count = count - oc.getPlusNum();
                                DrugWareHousingDetail detail = new DrugWareHousingDetail();
                                detail.setId(oc.getWarehousingId());
                                detail.setLeftCount(det.getLeftCount() + oc.getPlusNum());
                                drugWareHousingDetailService.updateById(detail);
                                orderComfire.setPlusNum(0);
                                orderComfireService.updateById(orderComfire);
                            }

                        }

                        //修改库存
                        Drug drug = drugService.getById(infoDrug.getDrugId());
                        Drug tempDrug = new Drug();
                        tempDrug.setId(infoDrug.getDrugId());
                        tempDrug.setStock(drug.getStock() + infoDrug.getQuantity());
                        drugService.updateById(tempDrug);
                    }
                    //修改详情
                    infoDrugService.updateById(temp);
                    //退款明细记录
                    prescriptionRefundDetail.setRefundNum(infoDrug.getQuantity());
                    prescriptionRefundDetail.setPharmacyId(infoDrug.getPharmacyId());
                    prescriptionRefundDetail.setBusinessId(infoDrug.getId().toString());
                    prescriptionRefundDetail.setProjectId(infoDrug.getDrugId().toString());
                    prescriptionRefundDetail.setName(infoDrug.getDrugName());
                    prescriptionRefundDetail.setRefund(infoDrug.getDiscountPrice().multiply(BigDecimal.valueOf(infoDrug.getQuantity())));
                    prescriptionRefundDetail.setRefundPrice(prescriptionRefundDetail.getRefund().multiply(order.getDrugDiscount()).multiply(order.getAllDiscount()));
                    prescriptionRefundDetail.setRefundNo(refundNo);
                    prescriptionRefundDetail.setRefundType(1);
                    prescriptionRefundDetail.setOrderNo(order.getOrderNo());
                    prescriptionRefundDetail.setInfoNo(infoDrug.getInfoNo());
                    list.add(prescriptionRefundDetail);
                    total = total.add(prescriptionRefundDetail.getRefundPrice());
                    noTotal = noTotal.add(prescriptionRefundDetail.getRefund());
                }
                //有药材加工费
                if (info.getProcessCost() != null && info.getProcessCost().compareTo(BigDecimal.ZERO) == 1) {
                    //退药材加工费
                    PrescriptionRefundDetail prescriptionRefundDetail = new PrescriptionRefundDetail();
                    prescriptionRefundDetail.setRefundNum(1);
                    prescriptionRefundDetail.setPharmacyId(order.getPharmacyId());
                    prescriptionRefundDetail.setBusinessId(info.getId().toString());
                    prescriptionRefundDetail.setProjectId("3");
                    prescriptionRefundDetail.setName("药材加工费");
                    prescriptionRefundDetail.setRefund(info.getProcessCost());
                    prescriptionRefundDetail.setRefundPrice(info.getProcessCost().multiply(order.getAllDiscount()));
                    prescriptionRefundDetail.setRefundNo(refundNo);
                    prescriptionRefundDetail.setRefundType(3);
                    prescriptionRefundDetail.setOrderNo(order.getOrderNo());
                    prescriptionRefundDetail.setInfoNo(info.getInfoNo());
                    list.add(prescriptionRefundDetail);
                    total = total.add(prescriptionRefundDetail.getRefundPrice());
                    noTotal = noTotal.add(info.getProcessCost());
                }
            }
        }
        //退款单记录
        PrescriptionRefund prescriptionRefund = new PrescriptionRefund();
        prescriptionRefund.setRefundNo(refundNo);
        prescriptionRefund.setRefundMsg(refundOrderDto.getMsg());
        prescriptionRefund.setOrderNo(order.getOrderNo());
        prescriptionRefund.setPharmacyId(order.getPharmacyId());
        prescriptionRefund.setRefundPrice(total);
        prescriptionRefund.setRefund(noTotal);
        prescriptionRefund.setActRefund(total);
        prescriptionRefund.setRefundTime(new Date());
        prescriptionRefundService.save(prescriptionRefund);
        prescriptionRefundDetailService.saveBatch(list);

        //查询订单里处方是否还存在没有退款，或部分退款的订单
        long count = infoService.count(Wrappers.<Info>query().lambda().eq(Info::getOrderNo, order.getOrderNo()).eq(Info::getDeleteFlag, 0).and(
                wrapper -> wrapper.eq(Info::getPayStatus, 1).or().eq(Info::getPayStatus, 2)
        ));
        int payStatus = 3;
        if (count <= 0) {
            boolean other = false;
            boolean exp = false;
            if (order.getOtherFee() != null && order.getOtherFee().compareTo(BigDecimal.ZERO) == 1) {
                //存在其他费用
                long count1 = prescriptionRefundDetailService.count(Wrappers.<PrescriptionRefundDetail>query().lambda().eq(PrescriptionRefundDetail::getOrderNo, order.getOrderNo()).eq(PrescriptionRefundDetail::getRefundType, 5));
                if (count1 > 0) {
                    other = true;
                }
            } else {
                other = true;
            }
            if (order.getExpressFee() != null && order.getExpressFee().compareTo(BigDecimal.ZERO) == 1) {
                //存在其他费用
                long count1 = prescriptionRefundDetailService.count(Wrappers.<PrescriptionRefundDetail>query().lambda().eq(PrescriptionRefundDetail::getOrderNo, order.getOrderNo()).eq(PrescriptionRefundDetail::getRefundType, 4));
                if (count1 > 0) {
                    exp = true;
                }
            } else {
                exp = true;
            }
            if (other && exp) {
                payStatus = 4;
            }
        }
        PrescriptionOrder prescriptionOrder = new PrescriptionOrder();
        prescriptionOrder.setId(order.getId());
        prescriptionOrder.setPayStatus(payStatus);
        prescriptionOrder.setRefundFlag(2);
        this.updateById(prescriptionOrder);


//        JSONObject jsonObject=new JSONObject();
//        jsonObject.put("status","1");
//        jsonObject.put("message","退款成功");
        return new ResponseEntity(true, HttpStatus.OK);
    }

}
